{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1d750c37-42b1-44fd-850d-2eb5c3e8e519",
   "metadata": {},
   "source": [
    "# Clickhouse\n",
    "\n",
    "In this tutorial, we'll see how to query Clickhouse from Jupyter. Optionally, you can spin up a testing server.\n",
    "\n",
    "```{tip}\n",
    "If you encounter issues, feel free to join our [community](https://ploomber.io/community) and we'll be happy to help!\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7289d7b0-b3fb-4789-a28e-f0c20871b95b",
   "metadata": {},
   "source": [
    "## Pre-requisites\n",
    "\n",
    "To run this tutorial, you need to install the `clickhouse-sqlalchemy` package.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "991ac184-6c73-4349-ad3f-4bc8e1c4130c",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install clickhouse-sqlalchemy --quiet"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5aee2f8a-eb94-433e-8afb-42b5f2f6c517",
   "metadata": {},
   "source": [
    "## Start Clickhoouse instance\n",
    "\n",
    "If you don't have a Clickhouse server running or you want to spin up one for testing, you can do it with the official [Docker image](https://hub.docker.com/r/clickhouse/clickhouse-server/).\n",
    "\n",
    "To start the server:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "id": "18fe0b54-da3c-4536-b24b-c77710ca3f68",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cefe171d72a8b46a529dc15105dca08e1c7cfa90aabbbcb32ffe023d22418ee9\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "docker run --detach --name clickhouse \\\n",
    "    -e CLICKHOUSE_DB=my_database \\\n",
    "    -e CLICKHOUSE_USER=username \\\n",
    "    -e CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 \\\n",
    "    -e CLICKHOUSE_PASSWORD=password \\\n",
    "    -p 9000:9000/tcp clickhouse/clickhouse-server"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29d89318-a5ee-4714-9cf2-b6fe5be85a86",
   "metadata": {},
   "source": [
    "Ensure that the container is running:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "id": "f5e27d59-4315-41bd-b633-e543a880a260",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CONTAINER ID   IMAGE                          COMMAND            CREATED         STATUS        PORTS                                        NAMES\n",
      "cefe171d72a8   clickhouse/clickhouse-server   \"/entrypoint.sh\"   2 seconds ago   Up 1 second   8123/tcp, 9009/tcp, 0.0.0.0:9000->9000/tcp   clickhouse\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "docker ps"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f59a529-4c3e-4633-9d44-227a6a8f90ab",
   "metadata": {},
   "source": [
    "## Load sample data\n",
    "\n",
    "We'll now uplod sample data.\n",
    "\n",
    "First, let's install and load JupySQL:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "0a1c8ecd-29a2-4d21-a64d-b358f2bb683e",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Note: you may need to restart the kernel to use updated packages.\n",
      "The sql extension is already loaded. To reload it, use:\n",
      "  %reload_ext sql\n"
     ]
    }
   ],
   "source": [
    "%pip install jupysql --quiet\n",
    "%load_ext sql"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "268ec8f0-bd22-4aa4-bae9-4450a55ab23a",
   "metadata": {},
   "source": [
    "Start the connection:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "id": "96405dc1-bdc8-4008-96f8-6ee7074ac899",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%sql clickhouse+native://username:password@localhost/my_database"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "472536e5-006a-4948-968b-5a8141db0393",
   "metadata": {},
   "source": [
    "Create a table:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "id": "1437f23d-759e-4f55-a0b6-2f173887fec8",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "*  clickhouse+native://username:***@localhost/my_database\n",
      "Done.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table>\n",
       "    <thead>\n",
       "        <tr>\n",
       "        </tr>\n",
       "    </thead>\n",
       "    <tbody>\n",
       "    </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%sql\n",
    "CREATE TABLE taxi\n",
    "(\n",
    "    VendorID Int32,\n",
    "    tpep_pickup_datetime DateTime,\n",
    "    tpep_dropoff_datetime DateTime,\n",
    "    passenger_count Float32,\n",
    "    trip_distance Float32,\n",
    "    RatecodeID Float32,\n",
    "    store_and_fwd_flag String,\n",
    "    PULocationID Int32,\n",
    "    DOLocationID Int32,\n",
    "    payment_type Int32,\n",
    "    fare_amount Float32,\n",
    "    extra Float32,\n",
    "    mta_tax Float32,\n",
    "    tip_amount Float32,\n",
    "    tolls_amount Float32,\n",
    "    improvement_surcharge Float32,\n",
    "    total_amount Float32,\n",
    "    congestion_surcharge Float32,\n",
    "    airport_fee Float32\n",
    ")\n",
    "ENGINE = MergeTree()\n",
    "PRIMARY KEY (VendorID)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c4385d6-6a35-4c35-8f47-24ee40e81143",
   "metadata": {
    "tags": []
   },
   "source": [
    "Now, we'll load 1.4 million rows into our table.\n",
    "\n",
    "If you're using the Docker container, you can execute the following in a terminal to start a bash session:\n",
    "\n",
    "```sh\n",
    "docker exec -it clickhouse bash\n",
    "```\n",
    "\n",
    "Now, to load the data:\n",
    "\n",
    "```sh\n",
    "apt update\n",
    "apt install curl -y\n",
    "\n",
    "curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet | clickhouse-client --query=\"INSERT INTO my_database.taxi FORMAT Parquet\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d63893c0-6eef-4728-bbc1-d625b00d2d1e",
   "metadata": {},
   "source": [
    "## Query\n",
    "\n",
    "Let's query our data!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "b3c6ef9c-c15d-4746-8a75-5dc633b5f123",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "*  clickhouse+native://username:***@localhost/my_database\n",
      "Done.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table>\n",
       "    <thead>\n",
       "        <tr>\n",
       "            <th>VendorID</th>\n",
       "            <th>tpep_pickup_datetime</th>\n",
       "            <th>tpep_dropoff_datetime</th>\n",
       "            <th>passenger_count</th>\n",
       "            <th>trip_distance</th>\n",
       "            <th>RatecodeID</th>\n",
       "            <th>store_and_fwd_flag</th>\n",
       "            <th>PULocationID</th>\n",
       "            <th>DOLocationID</th>\n",
       "            <th>payment_type</th>\n",
       "            <th>fare_amount</th>\n",
       "            <th>extra</th>\n",
       "            <th>mta_tax</th>\n",
       "            <th>tip_amount</th>\n",
       "            <th>tolls_amount</th>\n",
       "            <th>improvement_surcharge</th>\n",
       "            <th>total_amount</th>\n",
       "            <th>congestion_surcharge</th>\n",
       "            <th>airport_fee</th>\n",
       "        </tr>\n",
       "    </thead>\n",
       "    <tbody>\n",
       "        <tr>\n",
       "            <td>1</td>\n",
       "            <td>2021-01-01 00:30:10</td>\n",
       "            <td>2021-01-01 00:36:12</td>\n",
       "            <td>1.0</td>\n",
       "            <td>2.0999999046325684</td>\n",
       "            <td>1.0</td>\n",
       "            <td>N</td>\n",
       "            <td>142</td>\n",
       "            <td>43</td>\n",
       "            <td>2</td>\n",
       "            <td>8.0</td>\n",
       "            <td>3.0</td>\n",
       "            <td>0.5</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.30000001192092896</td>\n",
       "            <td>11.800000190734863</td>\n",
       "            <td>2.5</td>\n",
       "            <td>0.0</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>1</td>\n",
       "            <td>2021-01-01 00:51:20</td>\n",
       "            <td>2021-01-01 00:52:19</td>\n",
       "            <td>1.0</td>\n",
       "            <td>0.20000000298023224</td>\n",
       "            <td>1.0</td>\n",
       "            <td>N</td>\n",
       "            <td>238</td>\n",
       "            <td>151</td>\n",
       "            <td>2</td>\n",
       "            <td>3.0</td>\n",
       "            <td>0.5</td>\n",
       "            <td>0.5</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.30000001192092896</td>\n",
       "            <td>4.300000190734863</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.0</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>1</td>\n",
       "            <td>2021-01-01 00:43:30</td>\n",
       "            <td>2021-01-01 01:11:06</td>\n",
       "            <td>1.0</td>\n",
       "            <td>14.699999809265137</td>\n",
       "            <td>1.0</td>\n",
       "            <td>N</td>\n",
       "            <td>132</td>\n",
       "            <td>165</td>\n",
       "            <td>1</td>\n",
       "            <td>42.0</td>\n",
       "            <td>0.5</td>\n",
       "            <td>0.5</td>\n",
       "            <td>8.649999618530273</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.30000001192092896</td>\n",
       "            <td>51.95000076293945</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.0</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>1</td>\n",
       "            <td>2021-01-01 00:15:48</td>\n",
       "            <td>2021-01-01 00:31:01</td>\n",
       "            <td>0.0</td>\n",
       "            <td>10.600000381469727</td>\n",
       "            <td>1.0</td>\n",
       "            <td>N</td>\n",
       "            <td>138</td>\n",
       "            <td>132</td>\n",
       "            <td>1</td>\n",
       "            <td>29.0</td>\n",
       "            <td>0.5</td>\n",
       "            <td>0.5</td>\n",
       "            <td>6.050000190734863</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.30000001192092896</td>\n",
       "            <td>36.349998474121094</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.0</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>1</td>\n",
       "            <td>2021-01-01 00:16:29</td>\n",
       "            <td>2021-01-01 00:24:30</td>\n",
       "            <td>1.0</td>\n",
       "            <td>1.600000023841858</td>\n",
       "            <td>1.0</td>\n",
       "            <td>N</td>\n",
       "            <td>224</td>\n",
       "            <td>68</td>\n",
       "            <td>1</td>\n",
       "            <td>8.0</td>\n",
       "            <td>3.0</td>\n",
       "            <td>0.5</td>\n",
       "            <td>2.3499999046325684</td>\n",
       "            <td>0.0</td>\n",
       "            <td>0.30000001192092896</td>\n",
       "            <td>14.149999618530273</td>\n",
       "            <td>2.5</td>\n",
       "            <td>0.0</td>\n",
       "        </tr>\n",
       "    </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "[(1, datetime.datetime(2021, 1, 1, 0, 30, 10), datetime.datetime(2021, 1, 1, 0, 36, 12), 1.0, 2.0999999046325684, 1.0, 'N', 142, 43, 2, 8.0, 3.0, 0.5, 0.0, 0.0, 0.30000001192092896, 11.800000190734863, 2.5, 0.0),\n",
       " (1, datetime.datetime(2021, 1, 1, 0, 51, 20), datetime.datetime(2021, 1, 1, 0, 52, 19), 1.0, 0.20000000298023224, 1.0, 'N', 238, 151, 2, 3.0, 0.5, 0.5, 0.0, 0.0, 0.30000001192092896, 4.300000190734863, 0.0, 0.0),\n",
       " (1, datetime.datetime(2021, 1, 1, 0, 43, 30), datetime.datetime(2021, 1, 1, 1, 11, 6), 1.0, 14.699999809265137, 1.0, 'N', 132, 165, 1, 42.0, 0.5, 0.5, 8.649999618530273, 0.0, 0.30000001192092896, 51.95000076293945, 0.0, 0.0),\n",
       " (1, datetime.datetime(2021, 1, 1, 0, 15, 48), datetime.datetime(2021, 1, 1, 0, 31, 1), 0.0, 10.600000381469727, 1.0, 'N', 138, 132, 1, 29.0, 0.5, 0.5, 6.050000190734863, 0.0, 0.30000001192092896, 36.349998474121094, 0.0, 0.0),\n",
       " (1, datetime.datetime(2021, 1, 1, 0, 16, 29), datetime.datetime(2021, 1, 1, 0, 24, 30), 1.0, 1.600000023841858, 1.0, 'N', 224, 68, 1, 8.0, 3.0, 0.5, 2.3499999046325684, 0.0, 0.30000001192092896, 14.149999618530273, 2.5, 0.0)]"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%sql\n",
    "SELECT * FROM taxi LIMIT 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "333a522a-0915-448d-b340-9de36a6d4112",
   "metadata": {},
   "source": [
    "List the tables in the database:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "id": "35bca488-a529-457d-8816-c8063c53df50",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "    <thead>\n",
       "        <tr>\n",
       "            <th>Name</th>\n",
       "        </tr>\n",
       "    </thead>\n",
       "    <tbody>\n",
       "        <tr>\n",
       "            <td>taxi</td>\n",
       "        </tr>\n",
       "    </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "+------+\n",
       "| Name |\n",
       "+------+\n",
       "| taxi |\n",
       "+------+"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%sqlcmd tables"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74602a3f-7197-442a-9326-c317dd506f83",
   "metadata": {},
   "source": [
    "List columns in the taxi table:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "id": "119d1931-bd6f-475d-868c-3a1481e4ae37",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "    <thead>\n",
       "        <tr>\n",
       "            <th>name</th>\n",
       "            <th>type</th>\n",
       "            <th>nullable</th>\n",
       "            <th>default</th>\n",
       "            <th>comment</th>\n",
       "        </tr>\n",
       "    </thead>\n",
       "    <tbody>\n",
       "        <tr>\n",
       "            <td>VendorID</td>\n",
       "            <td>Int32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>tpep_pickup_datetime</td>\n",
       "            <td>DateTime</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>tpep_dropoff_datetime</td>\n",
       "            <td>DateTime</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>passenger_count</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>trip_distance</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>RatecodeID</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>store_and_fwd_flag</td>\n",
       "            <td>String</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>PULocationID</td>\n",
       "            <td>Int32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>DOLocationID</td>\n",
       "            <td>Int32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>payment_type</td>\n",
       "            <td>Int32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>fare_amount</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>extra</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>mta_tax</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>tip_amount</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>tolls_amount</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>improvement_surcharge</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>total_amount</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>congestion_surcharge</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "        <tr>\n",
       "            <td>airport_fee</td>\n",
       "            <td>Float32</td>\n",
       "            <td>False</td>\n",
       "            <td>None</td>\n",
       "            <td>None</td>\n",
       "        </tr>\n",
       "    </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "+-----------------------+----------+----------+---------+---------+\n",
       "|          name         |   type   | nullable | default | comment |\n",
       "+-----------------------+----------+----------+---------+---------+\n",
       "|        VendorID       |  Int32   |  False   |   None  |   None  |\n",
       "|  tpep_pickup_datetime | DateTime |  False   |   None  |   None  |\n",
       "| tpep_dropoff_datetime | DateTime |  False   |   None  |   None  |\n",
       "|    passenger_count    | Float32  |  False   |   None  |   None  |\n",
       "|     trip_distance     | Float32  |  False   |   None  |   None  |\n",
       "|       RatecodeID      | Float32  |  False   |   None  |   None  |\n",
       "|   store_and_fwd_flag  |  String  |  False   |   None  |   None  |\n",
       "|      PULocationID     |  Int32   |  False   |   None  |   None  |\n",
       "|      DOLocationID     |  Int32   |  False   |   None  |   None  |\n",
       "|      payment_type     |  Int32   |  False   |   None  |   None  |\n",
       "|      fare_amount      | Float32  |  False   |   None  |   None  |\n",
       "|         extra         | Float32  |  False   |   None  |   None  |\n",
       "|        mta_tax        | Float32  |  False   |   None  |   None  |\n",
       "|       tip_amount      | Float32  |  False   |   None  |   None  |\n",
       "|      tolls_amount     | Float32  |  False   |   None  |   None  |\n",
       "| improvement_surcharge | Float32  |  False   |   None  |   None  |\n",
       "|      total_amount     | Float32  |  False   |   None  |   None  |\n",
       "|  congestion_surcharge | Float32  |  False   |   None  |   None  |\n",
       "|      airport_fee      | Float32  |  False   |   None  |   None  |\n",
       "+-----------------------+----------+----------+---------+---------+"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%sqlcmd columns --table taxi"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8463de0-a361-48bd-a8d9-606599eec974",
   "metadata": {},
   "source": [
    "## Plotting\n",
    "\n",
    "Let's compute the 99th quantile of the `trip_distance` column to remove outliers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "id": "293620bf-2c27-4e04-b991-613c6113fc85",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "*  clickhouse+native://username:***@localhost/my_database\n",
      "Done.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table>\n",
       "    <thead>\n",
       "        <tr>\n",
       "            <th>quantile(0.99)(trip_distance)</th>\n",
       "        </tr>\n",
       "    </thead>\n",
       "    <tbody>\n",
       "        <tr>\n",
       "            <td>19.21179912567139</td>\n",
       "        </tr>\n",
       "    </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "[(19.21179912567139,)]"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%sql\n",
    "SELECT quantile(0.99)(trip_distance)\n",
    "FROM taxi"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25a61949-30db-4b47-b90f-3dee151b98a3",
   "metadata": {},
   "source": [
    "We now use `--save` to store this SQL SELECT statement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "id": "5b8593b4-ab53-4ca9-8f03-1f8df6c8088f",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "*  clickhouse+native://username:***@localhost/my_database\n",
      "Skipping execution...\n"
     ]
    }
   ],
   "source": [
    "%%sql --save no_outliers --no-execute\n",
    "SELECT trip_distance\n",
    "FROM taxi\n",
    "WHERE trip_distance < 18.7"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e371e6a-05ee-4f0b-a7fd-44cdd1bda522",
   "metadata": {},
   "source": [
    "Now, we can pass it to the plotting command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "id": "9065fef3-be9b-4422-9711-079729bd2b67",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: title={'center': \"'trip_distance' from 'no_outliers'\"}, xlabel='trip_distance', ylabel='Count'>"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlUAAAHHCAYAAACWQK1nAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy88F64QAAAACXBIWXMAAA9hAAAPYQGoP6dpAABBX0lEQVR4nO3deVwVdf///+dB2RSBVBZJBCTXXChSxFwqSTQyTSu1rhIjbRFLLdOuStH6XJbWlS2mLVdiV5e2XKVdqaGIWyWauVSampampuAKKC4ovH9/9ON8PbLjKBx93G+3c7t5Zl4z85oz58SzmfeZYzPGGAEAAOCCuFR1AwAAAJcDQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFVANJCcny2azadeuXZd0uzabTUlJSVXehzP497//rebNm8vV1VW+vr5V3Q7OExoaqvj4ePvz5cuXy2azafny5VXWE648hCrgAhSGkHO9/fbbSk5OrpqGqsCJEyeUlJTklH+8kpKSFBoaWmbd1q1bFR8fr/DwcL333nt69913L35zFyA+Pl433XRTVbdhuVWrVikpKUlZWVlV3UqpbrrpJoeAhysHoQqwWGVC1f3336+TJ08qJCTk4jR1Efs4ceKEJkyY4JShqryWL1+ugoICvf7664qPj9c999xT1S1dkVatWqUJEyaUK1R16dJFJ0+eVJcuXS5+Y8D/j1AFVKHc3FxJUo0aNeTh4VHkrNelVl36qG4OHDggSWVe9jPG6OTJk5egI5TFxcVFHh4ecnGx5s9c4WcVKA2hCrBQaGioNm/erBUrVshms8lms9kvwxReKlyxYoUee+wx+fv7q2HDhg7zzh3LFBoaqttvv12LFy9WRESEPDw81LJlS33xxRcV7uv06dMaOXKk/Pz8VKdOHd1xxx3au3dvkbri+vjhhx8UGxur+vXry9PTU2FhYXrwwQclSbt27ZKfn58kacKECfZ9Lhyn9dNPPyk+Pl6NGzeWh4eHAgMD9eCDD+rw4cMO201KSpLNZtOOHTsUHx8vX19f+fj4aPDgwTpx4kSRPj/66CO1b99etWrV0lVXXaUuXbpo8eLFDjVff/21OnfurNq1a6tOnTqKi4vT5s2bK/zahYaGavz48ZIkPz8/h/0rPEaLFi3SDTfcIE9PT73zzjuSpN9//11333236tatq1q1aqlDhw5asGCBw7oLx/18+umnmjBhgq6++mrVqVNHd911l7Kzs3X69GmNGDFC/v7+8vLy0uDBg3X69OkK78OuXbtks9n0yiuv6N1331V4eLjc3d3Vrl07rV27tkj90qVL7a+dr6+vevfurS1btlR4u7m5uXryyScVHBwsd3d3NWvWTK+88oqMMUV6K+7s7rmvdVJSkkaPHi1JCgsLs7/XShr/V9KYqjVr1qhHjx7y8fFRrVq11LVrV3333XcONYXvx19++UX33nuvrrrqKnXq1EmSlJGRocGDB6thw4Zyd3dXgwYN1Lt3b8YhQpJUs6obAC4nU6dO1fDhw+Xl5aVnn31WkhQQEOBQ89hjj8nPz0/jxo0r8/9+t2/frv79++uRRx7RoEGDNHPmTN19991KSUnRrbfeWu6+HnroIX300Ue699571bFjRy1dulRxcXFlLnfgwAF1795dfn5+Gjt2rHx9fbVr1y57sPPz89P06dP16KOP6s4771Tfvn0lSW3atJEkpaam6vfff9fgwYMVGBiozZs3691339XmzZu1evXqImfE7rnnHoWFhWnSpElav3693n//ffn7++vll1+210yYMEFJSUnq2LGjJk6cKDc3N61Zs0ZLly5V9+7dJf01qHzQoEGKjY3Vyy+/rBMnTmj69Onq1KmTNmzYUK5xVIWmTp2qDz/8UHPnztX06dPl5eVl3z9J2rZtmwYOHKiHH35YQ4YMUbNmzZSZmamOHTvqxIkTevzxx1WvXj3NmjVLd9xxh/773//qzjvvdNjGpEmT5OnpqbFjx2rHjh1688035erqKhcXFx09elRJSUlavXq1kpOTFRYWpnHjxpW7/3PNnj1bx44d08MPPyybzabJkyerb9+++v333+Xq6ipJWrJkiXr27KnGjRsrKSlJJ0+e1Jtvvqkbb7xR69evL/drZ4zRHXfcoWXLlikhIUERERFatGiRRo8erT///FOvvfZahXrv27evfv31V82ZM0evvfaa6tevL0n2UF8eS5cuVc+ePRUZGanx48fLxcVFM2fO1C233KJvvvlG7du3d6i/++671aRJE/3jH/+wB8F+/fpp8+bNGj58uEJDQ3XgwAGlpqZq9+7dFXpf4TJlAFjq2muvNV27di0yfebMmUaS6dSpkzl79myx83bu3GmfFhISYiSZzz//3D4tOzvbNGjQwFx33XXl7mfjxo1Gknnsscccpt97771Gkhk/fnyJfcydO9dIMmvXri1x/QcPHiyynkInTpwoMm3OnDlGklm5cqV92vjx440k8+CDDzrU3nnnnaZevXr259u3bzcuLi7mzjvvNPn5+Q61BQUFxhhjjh07Znx9fc2QIUMc5mdkZBgfH58i08ujsL+DBw86TC88RikpKQ7TR4wYYSSZb775xj7t2LFjJiwszISGhtp7X7ZsmZFkWrVqZfLy8uy1AwcONDabzfTs2dNhvdHR0SYkJKTC/e/cudNIMvXq1TNHjhyxT//yyy+NJPPVV1/Zp0VERBh/f39z+PBh+7Qff/zRuLi4mAceeKDc25w3b56RZF588UWH6XfddZex2Wxmx44dDr3NnDmzyDrOf19NmTKlyOekUEhIiBk0aJD9eeFru2zZMmPMX++PJk2amNjYWPt7xZi/3qNhYWHm1ltvtU8rPN4DBw502MbRo0eNJDNlypRyvgq40nD5D7jEhgwZoho1apSrNigoyOGshre3tx544AFt2LBBGRkZ5VrHwoULJUmPP/64w/QRI0aUuWzhGKL58+frzJkz5dreuTw9Pe3/PnXqlA4dOqQOHTpIktavX1+k/pFHHnF43rlzZx0+fFg5OTmSpHnz5qmgoEDjxo0rMlam8KxXamqqsrKyNHDgQB06dMj+qFGjhqKiorRs2bIK70dpwsLCFBsb6zBt4cKFat++vf2SkSR5eXlp6NCh2rVrl3755ReH+gceeMB+pkiSoqKiZIyxX2Y9d/qePXt09uzZSvXav39/XXXVVfbnnTt3lvTXpUpJ2r9/vzZu3Kj4+HjVrVvXXtemTRvdeuut9vdSeSxcuFA1atQo8r578sknZYzR119/Xal9qKyNGzdq+/btuvfee3X48GH7+yI3N1fdunXTypUrVVBQ4LDM+e9HT09Pubm5afny5Tp69OilbB9OglAFXGJhYWHlrr3mmmuKXCJr2rSpJJV7DMcff/whFxcXhYeHO0xv1qxZmct27dpV/fr104QJE1S/fn317t1bM2fOLPe4niNHjuiJJ55QQECAPD095efnZ9//7OzsIvWNGjVyeF4YAAr/gP32229ycXFRy5YtS9zm9u3bJUm33HKL/Pz8HB6LFy+2Dzq3SnHH848//ij29W3RooV9/rnO328fHx9JUnBwcJHpBQUFxb525VHW61vYV0m9F4aQ8vjjjz8UFBSkOnXqFFnPudu6VArfF4MGDSryvnj//fd1+vTpIq/r+cfW3d1dL7/8sr7++msFBASoS5cumjx5crn/BweXP8ZUAZfYuWdvqjubzab//ve/Wr16tb766istWrRIDz74oF599VWtXr1aXl5epS5/zz33aNWqVRo9erQiIiLk5eWlgoIC9ejRo8hZAUklnsEz5wxsLkvhev/9738rMDCwyPyaNa39z54Vx7Ok/bbi9biY67NCSd80zc/Pt3Q7he+LKVOmKCIiotia89/PxR3bESNGqFevXpo3b54WLVqk559/XpMmTdLSpUt13XXXWdoznA+hCrCYlbcj2LFjh4wxDuv89ddfJancg2JDQkJUUFCg3377zeEMxLZt28rdR4cOHdShQwf93//9n2bPnq377rtPH3/8sR566KES9/fo0aNKS0vThAkTHAZWF54xqIzw8HAVFBTol19+KfEPY+EZOX9/f8XExFR6WxciJCSk2Nd369at9vnVUWFfJfVev3591a5du9zrWrJkiY4dO+Zwtur816DwbNn5954q7kzWhXy2Ct8X3t7eF/y+CA8P15NPPqknn3xS27dvV0REhF599VV99NFHF7ReOD8u/wEWq127tmV3fN63b5/mzp1rf56Tk6MPP/xQERERxZ6FKU7Pnj0lSW+88YbD9KlTp5a57NGjR4ucxSgMM4WXAGvVqiWp6B/FwrMi5y9fnu2WpE+fPnJxcdHEiROLnOkq3E5sbKy8vb31j3/8o9hxYAcPHqz09svrtttu0/fff6/09HT7tNzcXL377rsKDQ0t9fJlVWrQoIEiIiI0a9Ysh+O5adMmLV68WLfddlu513XbbbcpPz9fb731lsP01157TTabzf6+9Pb2Vv369bVy5UqHurfffrvIOgsDXWU+X5GRkQoPD9crr7yi48ePF5lfnvfFiRMndOrUKYdp4eHhqlOnTqVudYHLD2eqAItFRkZq+vTpevHFF3XNNdfI399ft9xyS6XW1bRpUyUkJGjt2rUKCAjQBx98oMzMTM2cObPc64iIiNDAgQP19ttvKzs7Wx07dlRaWpp27NhR5rKzZs3S22+/rTvvvFPh4eE6duyY3nvvPXl7e9v/wHp6eqply5b65JNP1LRpU9WtW1etWrVSq1at7GNOzpw5o6uvvlqLFy/Wzp07K/VaSH+NMXv22Wf1wgsvqHPnzurbt6/c3d21du1aBQUFadKkSfL29tb06dN1//336/rrr9eAAQPk5+en3bt3a8GCBbrxxhuL/KG32tixYzVnzhz17NlTjz/+uOrWratZs2Zp586d+vzzzy27IeXFMGXKFPXs2VPR0dFKSEiw31LBx8fH4Xciy9KrVy/dfPPNevbZZ7Vr1y61bdtWixcv1pdffqkRI0Y4jPF76KGH9NJLL+mhhx7SDTfcoJUrV9rPyJ4rMjJSkvTss89qwIABcnV1Va9evcp19szFxUXvv/++evbsqWuvvVaDBw/W1VdfrT///FPLli2Tt7e3vvrqq1LX8euvv6pbt26655571LJlS9WsWVNz585VZmamBgwYUO7XBpexKvveIXCZysjIMHFxcaZOnTpGkv32CoW3Kyju9gQl3VIhLi7OLFq0yLRp08a4u7ub5s2bm88++6zCPZ08edI8/vjjpl69eqZ27dqmV69eZs+ePWXeUmH9+vVm4MCBplGjRsbd3d34+/ub22+/3fzwww8O61+1apWJjIw0bm5uDuvcu3evufPOO42vr6/x8fExd999t9m3b1+R7ZZ0y4LiXhdjjPnggw/MddddZ9zd3c1VV11lunbtalJTUx1qli1bZmJjY42Pj4/x8PAw4eHhJj4+vkjv5VHaLRXi4uKKXea3334zd911l/H19TUeHh6mffv2Zv78+UV6lFTkmJb0Ximpj7IU3raguFsBnH8sjDFmyZIl5sYbbzSenp7G29vb9OrVy/zyyy8V2qYxf91GYuTIkSYoKMi4urqaJk2amClTpjjc0sCYv25rkJCQYHx8fEydOnXMPffcYw4cOFBsby+88IK5+uqrjYuLi8N7o6xbKhTasGGD6du3r6lXr55xd3c3ISEh5p577jFpaWn2mpJe50OHDplhw4aZ5s2bm9q1axsfHx8TFRVlPv300wq/Nrg82YypwhGKAEoUGhqqVq1aaf78+VXdCgCgHKrvOWgAAAAnwpgqwImVdX8cT09P+z2PACvk5+eXOajby8urzNttAJcjQhXgxBo0aFDq/EGDBhX7Q7VAZe3Zs6fMG9iOHz++QoPagcsFoQqopspzx/TU1NRS5wcFBVnUDfCXwMDAMt93jRs3vkTdANULA9UBAAAswEB1AAAAC3D57xIqKCjQvn37VKdOHUt/ygQAAFw8xhgdO3ZMQUFBpd68l1B1Ce3bt6/Ir84DAADnsGfPHjVs2LDE+YSqS6jwR0X37Nkjb2/vKu4GAACUR05OjoKDgx1+HLw4hKpLqPCSn7e3N6EKAAAnU9bQHQaqAwAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAVqVnUDqF5Cxy4os2bXS3GXoBMAAJwLZ6oAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAlUaqiZNmqR27dqpTp068vf3V58+fbRt2zaHmlOnTmnYsGGqV6+evLy81K9fP2VmZjrU7N69W3FxcapVq5b8/f01evRonT171qFm+fLluv766+Xu7q5rrrlGycnJRfqZNm2aQkND5eHhoaioKH3//fcV7gUAAFyZqjRUrVixQsOGDdPq1auVmpqqM2fOqHv37srNzbXXjBw5Ul999ZU+++wzrVixQvv27VPfvn3t8/Pz8xUXF6e8vDytWrVKs2bNUnJyssaNG2ev2blzp+Li4nTzzTdr48aNGjFihB566CEtWrTIXvPJJ59o1KhRGj9+vNavX6+2bdsqNjZWBw4cKHcvAADgymUzxpiqbqLQwYMH5e/vrxUrVqhLly7Kzs6Wn5+fZs+erbvuukuStHXrVrVo0ULp6enq0KGDvv76a91+++3at2+fAgICJEkzZszQmDFjdPDgQbm5uWnMmDFasGCBNm3aZN/WgAEDlJWVpZSUFElSVFSU2rVrp7feekuSVFBQoODgYA0fPlxjx44tVy9lycnJkY+Pj7Kzs+Xt7W3pa2eV0LELyqzZ9VLcJegEAIDqobx/v6vVmKrs7GxJUt26dSVJ69at05kzZxQTE2Ovad68uRo1aqT09HRJUnp6ulq3bm0PVJIUGxurnJwcbd682V5z7joKawrXkZeXp3Xr1jnUuLi4KCYmxl5Tnl7Od/r0aeXk5Dg8AADA5anahKqCggKNGDFCN954o1q1aiVJysjIkJubm3x9fR1qAwIClJGRYa85N1AVzi+cV1pNTk6OTp48qUOHDik/P7/YmnPXUVYv55s0aZJ8fHzsj+Dg4HK+GgAAwNlUm1A1bNgwbdq0SR9//HFVt2KZZ555RtnZ2fbHnj17qrolAABwkdSs6gYkKTExUfPnz9fKlSvVsGFD+/TAwEDl5eUpKyvL4QxRZmamAgMD7TXnf0uv8Bt559ac/y29zMxMeXt7y9PTUzVq1FCNGjWKrTl3HWX1cj53d3e5u7tX4JUAAADOqkrPVBljlJiYqLlz52rp0qUKCwtzmB8ZGSlXV1elpaXZp23btk27d+9WdHS0JCk6Olo///yzw7f0UlNT5e3trZYtW9przl1HYU3hOtzc3BQZGelQU1BQoLS0NHtNeXoBAABXrio9UzVs2DDNnj1bX375perUqWMfm+Tj4yNPT0/5+PgoISFBo0aNUt26deXt7a3hw4crOjra/m277t27q2XLlrr//vs1efJkZWRk6LnnntOwYcPsZ4keeeQRvfXWW3r66af14IMPaunSpfr000+1YMH/+6bbqFGjNGjQIN1www1q3769pk6dqtzcXA0ePNjeU1m9AACAK1eVhqrp06dLkm666SaH6TNnzlR8fLwk6bXXXpOLi4v69eun06dPKzY2Vm+//ba9tkaNGpo/f74effRRRUdHq3bt2ho0aJAmTpxorwkLC9OCBQs0cuRIvf7662rYsKHef/99xcbG2mv69++vgwcPaty4ccrIyFBERIRSUlIcBq+X1QsAALhyVav7VF3uuE8VAADOxynvUwUAAOCsCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFqhZ1Q3A+YSOXVBmza6X4i5BJwAAVB+cqQIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALFCzqhvA5Sl07IIya3a9FHcJOgEA4NLgTBUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABao0VK1cuVK9evVSUFCQbDab5s2b5zA/Pj5eNpvN4dGjRw+HmiNHjui+++6Tt7e3fH19lZCQoOPHjzvU/PTTT+rcubM8PDwUHBysyZMnF+nls88+U/PmzeXh4aHWrVtr4cKFDvONMRo3bpwaNGggT09PxcTEaPv27da8EJdI6NgFZT4AAEDlVGmoys3NVdu2bTVt2rQSa3r06KH9+/fbH3PmzHGYf99992nz5s1KTU3V/PnztXLlSg0dOtQ+PycnR927d1dISIjWrVunKVOmKCkpSe+++669ZtWqVRo4cKASEhK0YcMG9enTR3369NGmTZvsNZMnT9Ybb7yhGTNmaM2aNapdu7ZiY2N16tQpC18RAADgrGzGGFPVTUiSzWbT3Llz1adPH/u0+Ph4ZWVlFTmDVWjLli1q2bKl1q5dqxtuuEGSlJKSottuu0179+5VUFCQpk+frmeffVYZGRlyc3OTJI0dO1bz5s3T1q1bJUn9+/dXbm6u5s+fb193hw4dFBERoRkzZsgYo6CgID355JN66qmnJEnZ2dkKCAhQcnKyBgwYUK59zMnJkY+Pj7Kzs+Xt7V3Rl+iCVbczUdynCgDgDMr797vaj6lavny5/P391axZMz366KM6fPiwfV56erp8fX3tgUqSYmJi5OLiojVr1thrunTpYg9UkhQbG6tt27bp6NGj9pqYmBiH7cbGxio9PV2StHPnTmVkZDjU+Pj4KCoqyl5TnNOnTysnJ8fhAQAALk/VOlT16NFDH374odLS0vTyyy9rxYoV6tmzp/Lz8yVJGRkZ8vf3d1imZs2aqlu3rjIyMuw1AQEBDjWFz8uqOXf+ucsVV1OcSZMmycfHx/4IDg6u0P4DAADnUa1/pubcy2qtW7dWmzZtFB4eruXLl6tbt25V2Fn5PPPMMxo1apT9eU5ODsEKAIDLVLU+U3W+xo0bq379+tqxY4ckKTAwUAcOHHCoOXv2rI4cOaLAwEB7TWZmpkNN4fOyas6df+5yxdUUx93dXd7e3g4PAABweXKqULV3714dPnxYDRo0kCRFR0crKytL69ats9csXbpUBQUFioqKstesXLlSZ86csdekpqaqWbNmuuqqq+w1aWlpDttKTU1VdHS0JCksLEyBgYEONTk5OVqzZo29BgAAXNmqNFQdP35cGzdu1MaNGyX9NSB848aN2r17t44fP67Ro0dr9erV2rVrl9LS0tS7d29dc801io2NlSS1aNFCPXr00JAhQ/T999/ru+++U2JiogYMGKCgoCBJ0r333is3NzclJCRo8+bN+uSTT/T66687XJZ74oknlJKSoldffVVbt25VUlKSfvjhByUmJkr665uJI0aM0Isvvqj//e9/+vnnn/XAAw8oKCjI4duKAADgylWlY6p++OEH3XzzzfbnhUFn0KBBmj59un766SfNmjVLWVlZCgoKUvfu3fXCCy/I3d3dvsx//vMfJSYmqlu3bnJxcVG/fv30xhtv2Of7+Pho8eLFGjZsmCIjI1W/fn2NGzfO4V5WHTt21OzZs/Xcc8/p73//u5o0aaJ58+apVatW9pqnn35aubm5Gjp0qLKystSpUyelpKTIw8PjYr5EAADASVSb+1RdCbhPlSPuUwUAcAaXzX2qAAAAnAGhCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAClQpVjRs31uHDh4tMz8rKUuPGjS+4KQAAAGdTqVC1a9cu5efnF5l++vRp/fnnnxfcFAAAgLOpWZHi//3vf/Z/L1q0SD4+Pvbn+fn5SktLU2hoqGXNAQAAOIsKhao+ffpIkmw2mwYNGuQwz9XVVaGhoXr11Vctaw4AAMBZVChUFRQUSJLCwsK0du1a1a9f/6I0BQAA4GwqFKoK7dy50+o+AAAAnFqlQpUkpaWlKS0tTQcOHLCfwSr0wQcfXHBjAAAAzqRSoWrChAmaOHGibrjhBjVo0EA2m83qvgAAAJxKpULVjBkzlJycrPvvv9/qfgAAAJxSpe5TlZeXp44dO1rdCwAAgNOq1Jmqhx56SLNnz9bzzz9vdT+4goSOXVDq/F0vxV2iTgAAuHCVClWnTp3Su+++qyVLlqhNmzZydXV1mP/Pf/7TkuYAAACcRaVC1U8//aSIiAhJ0qZNmxzmMWgdAABciSoVqpYtW2Z1HwAAAE6tUgPVAQAA4KhSZ6puvvnmUi/zLV26tNINAQAAOKNKharC8VSFzpw5o40bN2rTpk1FfmgZAADgSlCpUPXaa68VOz0pKUnHjx+/oIYAAACckaVjqv72t7/xu38AAOCKZGmoSk9Pl4eHh5WrBAAAcAqVuvzXt29fh+fGGO3fv18//PADd1kHAABXpEqFKh8fH4fnLi4uatasmSZOnKju3btb0hgAAIAzqVSomjlzptV9AAAAOLVKhapC69at05YtWyRJ1157ra677jpLmgIAAHA2lQpVBw4c0IABA7R8+XL5+vpKkrKysnTzzTfr448/lp+fn5U9AgAAVHuV+vbf8OHDdezYMW3evFlHjhzRkSNHtGnTJuXk5Ojxxx+3ukcAAIBqr1JnqlJSUrRkyRK1aNHCPq1ly5aaNm0aA9UBAMAVqVJnqgoKCuTq6lpkuqurqwoKCi64KQAAAGdTqVB1yy236IknntC+ffvs0/7880+NHDlS3bp1s6w5AAAAZ1GpUPXWW28pJydHoaGhCg8PV3h4uMLCwpSTk6M333zT6h4BAACqvUqNqQoODtb69eu1ZMkSbd26VZLUokULxcTEWNocAACAs6jQmaqlS5eqZcuWysnJkc1m06233qrhw4dr+PDhateuna699lp98803F6tXAACAaqtCoWrq1KkaMmSIvL29i8zz8fHRww8/rH/+85+WNQcAAOAsKhSqfvzxR/Xo0aPE+d27d9e6desuuCkAAABnU6FQlZmZWeytFArVrFlTBw8evOCmAAAAnE2FQtXVV1+tTZs2lTj/p59+UoMGDS64KQAAAGdToVB122236fnnn9epU6eKzDt58qTGjx+v22+/3bLmAAAAnEWFbqnw3HPP6YsvvlDTpk2VmJioZs2aSZK2bt2qadOmKT8/X88+++xFaRQAAKA6q1CoCggI0KpVq/Too4/qmWeekTFGkmSz2RQbG6tp06YpICDgojQKAABQnVX4juohISFauHChDh06pDVr1mj16tU6dOiQFi5cqLCwsAqta+XKlerVq5eCgoJks9k0b948h/nGGI0bN04NGjSQp6enYmJitH37doeaI0eO6L777pO3t7d8fX2VkJCg48ePO9T89NNP6ty5szw8PBQcHKzJkycX6eWzzz5T8+bN5eHhodatW2vhwoUV7gUAAFy5KvUzNZJ01VVXqV27dmrfvr2uuuqqSq0jNzdXbdu21bRp04qdP3nyZL3xxhuaMWOG1qxZo9q1ays2NtZhTNd9992nzZs3KzU1VfPnz9fKlSs1dOhQ+/ycnBx1795dISEhWrdunaZMmaKkpCS9++679ppVq1Zp4MCBSkhI0IYNG9SnTx/16dPHYVB+eXoBAABXLpspvIZXxWw2m+bOnas+ffpI+uvMUFBQkJ588kk99dRTkqTs7GwFBAQoOTlZAwYM0JYtW9SyZUutXbtWN9xwgyQpJSVFt912m/bu3augoCBNnz5dzz77rDIyMuTm5iZJGjt2rObNm2f/iZ3+/fsrNzdX8+fPt/fToUMHRUREaMaMGeXqpTxycnLk4+Oj7OzsYm+gerGFjl1wybd5IXa9FFfVLQAAUO6/35U+U3Wx7dy5UxkZGQ6/J+jj46OoqCilp6dLktLT0+Xr62sPVJIUExMjFxcXrVmzxl7TpUsXe6CSpNjYWG3btk1Hjx6115z/u4WxsbH27ZSnl+KcPn1aOTk5Dg8AAHB5qrahKiMjQ5KKDHwPCAiwz8vIyJC/v7/D/Jo1a6pu3boONcWt49xtlFRz7vyyeinOpEmT5OPjY38EBweXsdcAAMBZVdtQdTl45plnlJ2dbX/s2bOnqlsCAAAXSbUNVYGBgZL++mmcc2VmZtrnBQYG6sCBAw7zz549qyNHjjjUFLeOc7dRUs2588vqpTju7u7y9vZ2eAAAgMtTtQ1VYWFhCgwMVFpamn1aTk6O1qxZo+joaElSdHS0srKyHH7EeenSpSooKFBUVJS9ZuXKlTpz5oy9JjU1Vc2aNbN/azE6OtphO4U1hdspTy8AAODKVqWh6vjx49q4caM2btwo6a8B4Rs3btTu3btls9k0YsQIvfjii/rf//6nn3/+WQ888ICCgoLs3xBs0aKFevTooSFDhuj777/Xd999p8TERA0YMEBBQUGSpHvvvVdubm5KSEjQ5s2b9cknn+j111/XqFGj7H088cQTSklJ0auvvqqtW7cqKSlJP/zwgxITEyWpXL0AAIArW4XuqG61H374QTfffLP9eWHQGTRokJKTk/X0008rNzdXQ4cOVVZWljp16qSUlBR5eHjYl/nPf/6jxMREdevWTS4uLurXr5/eeOMN+3wfHx8tXrxYw4YNU2RkpOrXr69x48Y53MuqY8eOmj17tp577jn9/e9/V5MmTTRv3jy1atXKXlOeXgAAwJWr2tyn6krAfaoqhvtUAQCqA6e/TxUAAIAzIVQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFalZ1A0BJyvMD0PzoMgCguuBMFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGCBmlXdAHAhQscuKLNm10txl6ATAMCVjjNVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWKBah6qkpCTZbDaHR/Pmze3zT506pWHDhqlevXry8vJSv379lJmZ6bCO3bt3Ky4uTrVq1ZK/v79Gjx6ts2fPOtQsX75c119/vdzd3XXNNdcoOTm5SC/Tpk1TaGioPDw8FBUVpe+///6i7DMAAHBO1TpUSdK1116r/fv32x/ffvutfd7IkSP11Vdf6bPPPtOKFSu0b98+9e3b1z4/Pz9fcXFxysvL06pVqzRr1iwlJydr3Lhx9pqdO3cqLi5ON998szZu3KgRI0booYce0qJFi+w1n3zyiUaNGqXx48dr/fr1atu2rWJjY3XgwIFL8yIAAIBqz2aMMVXdREmSkpI0b948bdy4sci87Oxs+fn5afbs2brrrrskSVu3blWLFi2Unp6uDh066Ouvv9btt9+uffv2KSAgQJI0Y8YMjRkzRgcPHpSbm5vGjBmjBQsWaNOmTfZ1DxgwQFlZWUpJSZEkRUVFqV27dnrrrbckSQUFBQoODtbw4cM1duzYcu9PTk6OfHx8lJ2dLW9v78q+LJUWOnbBJd9mdbDrpbiqbgEA4MTK+/e72p+p2r59u4KCgtS4cWPdd9992r17tyRp3bp1OnPmjGJiYuy1zZs3V6NGjZSeni5JSk9PV+vWre2BSpJiY2OVk5OjzZs322vOXUdhTeE68vLytG7dOocaFxcXxcTE2GsAAABqVnUDpYmKilJycrKaNWum/fv3a8KECercubM2bdqkjIwMubm5ydfX12GZgIAAZWRkSJIyMjIcAlXh/MJ5pdXk5OTo5MmTOnr0qPLz84ut2bp1a6n9nz59WqdPn7Y/z8nJKf/OwzLlOUPH2SwAwIWq1qGqZ8+e9n+3adNGUVFRCgkJ0aeffipPT88q7Kx8Jk2apAkTJlR1GwAA4BKo9pf/zuXr66umTZtqx44dCgwMVF5enrKyshxqMjMzFRgYKEkKDAws8m3Awudl1Xh7e8vT01P169dXjRo1iq0pXEdJnnnmGWVnZ9sfe/bsqfA+AwAA5+BUoer48eP67bff1KBBA0VGRsrV1VVpaWn2+du2bdPu3bsVHR0tSYqOjtbPP//s8C291NRUeXt7q2XLlvaac9dRWFO4Djc3N0VGRjrUFBQUKC0tzV5TEnd3d3l7ezs8AADA5alah6qnnnpKK1as0K5du7Rq1SrdeeedqlGjhgYOHCgfHx8lJCRo1KhRWrZsmdatW6fBgwcrOjpaHTp0kCR1795dLVu21P33368ff/xRixYt0nPPPadhw4bJ3d1dkvTII4/o999/19NPP62tW7fq7bff1qeffqqRI0fa+xg1apTee+89zZo1S1u2bNGjjz6q3NxcDR48uEpeFwAAUP1U6zFVe/fu1cCBA3X48GH5+fmpU6dOWr16tfz8/CRJr732mlxcXNSvXz+dPn1asbGxevvtt+3L16hRQ/Pnz9ejjz6q6Oho1a5dW4MGDdLEiRPtNWFhYVqwYIFGjhyp119/XQ0bNtT777+v2NhYe03//v118OBBjRs3ThkZGYqIiFBKSkqRwesAAODKVa3vU3W54T5V1Rff/gMAlOSyuU8VAACAMyBUAQAAWKBaj6lC+XFpDwCAqsWZKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAPepAlS++3zxUzYAgNJwpgoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMACNau6AcBZhI5dUGbNrpfiLkEnAIDqiDNVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABYgVAEAAFiAUAUAAGABQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFqhZ1Q0Al5PQsQvKrNn1Utwl6AQAcKlxpgoAAMAChCoAAAALEKoAAAAsQKgCAACwAAPVgUusrMHsDGQHAOfEmSoAAAALEKoAAAAsQKgCAACwAKEKAADAAgxUB6oZ7soOAM6JM1UAAAAWIFQBAABYgFAFAABgAcZUAU6IcVcAUP1wpgoAAMAChCoAAAALEKoAAAAswJgq4DLFuCsAuLQIVcAVjOAFANbh8h8AAIAFOFMFoFSczQKA8iFUAbhgZQUvQheAKwGX/wAAACzAmSoAF115LiGWB2e8AFRnhCoAToPxXQCqM0IVgCsO4QzAxUCoAnBZsepSI4PvAVQUoQoAKoFxYgDOR6gCgCpEOAMuH4QqALgMWDVOjMueQOURqipo2rRpmjJlijIyMtS2bVu9+eabat++fVW3BQBlsuKsGIP8gZIRqirgk08+0ahRozRjxgxFRUVp6tSpio2N1bZt2+Tv71/V7QFAtWDVJU2rEPIqj2NZMTZjjKnqJpxFVFSU2rVrp7feekuSVFBQoODgYA0fPlxjx44tc/mcnBz5+PgoOztb3t7elvZW3d74AABYrapCVXn/fvMzNeWUl5endevWKSYmxj7NxcVFMTExSk9Pr8LOAABAdcDlv3I6dOiQ8vPzFRAQ4DA9ICBAW7duLXaZ06dP6/Tp0/bn2dnZkv5KvFYrOH3C8nUCAFCdXIy/nxXZblkX9whVF9GkSZM0YcKEItODg4OroBsAAJybz9Sq3f6xY8fk4+NT4nxCVTnVr19fNWrUUGZmpsP0zMxMBQYGFrvMM888o1GjRtmfFxQU6MiRI6pXr55sNttF7TcnJ0fBwcHas2eP5eO3qhv29fLEvl6+rqT9ZV8vD8YYHTt2TEFBQaXWEarKyc3NTZGRkUpLS1OfPn0k/RWS0tLSlJiYWOwy7u7ucnd3d5jm6+t7kTt15O3tfdm9uUvCvl6e2NfL15W0v+yr8yvtDFUhQlUFjBo1SoMGDdINN9yg9u3ba+rUqcrNzdXgwYOrujUAAFDFCFUV0L9/fx08eFDjxo1TRkaGIiIilJKSUmTwOgAAuPIQqiooMTGxxMt91Ym7u7vGjx9f5PLj5Yh9vTyxr5evK2l/2dcrCzf/BAAAsAA3/wQAALAAoQoAAMAChCoAAAALEKoAAAAsQKhyYtOmTVNoaKg8PDwUFRWl77//vtT6zz77TM2bN5eHh4dat26thQsXXqJOK2/SpElq166d6tSpI39/f/Xp00fbtm0rdZnk5GTZbDaHh4eHxyXquPKSkpKK9N28efNSl3HGYypJoaGhRfbVZrNp2LBhxdY72zFduXKlevXqpaCgINlsNs2bN89hvjFG48aNU4MGDeTp6amYmBht3769zPVW9DN/KZS2r2fOnNGYMWPUunVr1a5dW0FBQXrggQe0b9++UtdZmc/CpVDWcY2Pjy/Sd48ePcpcr7MdV0nFfn5tNpumTJlS4jqr63G1EqHKSX3yyScaNWqUxo8fr/Xr16tt27aKjY3VgQMHiq1ftWqVBg4cqISEBG3YsEF9+vRRnz59tGnTpkvcecWsWLFCw4YN0+rVq5WamqozZ86oe/fuys3NLXU5b29v7d+/3/74448/LlHHF+baa6916Pvbb78tsdZZj6kkrV271mE/U1NTJUl33313ics40zHNzc1V27ZtNW3atGLnT548WW+88YZmzJihNWvWqHbt2oqNjdWpU6dKXGdFP/OXSmn7euLECa1fv17PP/+81q9fry+++ELbtm3THXfcUeZ6K/JZuFTKOq6S1KNHD4e+58yZU+o6nfG4SnLYx/379+uDDz6QzWZTv379Sl1vdTyuljJwSu3btzfDhg2zP8/PzzdBQUFm0qRJxdbfc889Ji4uzmFaVFSUefjhhy9qn1Y7cOCAkWRWrFhRYs3MmTONj4/PpWvKIuPHjzdt27Ytd/3lckyNMeaJJ54w4eHhpqCgoNj5znpMjTFGkpk7d679eUFBgQkMDDRTpkyxT8vKyjLu7u5mzpw5Ja6nop/5qnD+vhbn+++/N5LMH3/8UWJNRT8LVaG4fR00aJDp3bt3hdZzuRzX3r17m1tuuaXUGmc4rheKM1VOKC8vT+vWrVNMTIx9mouLi2JiYpSenl7sMunp6Q71khQbG1tifXWVnZ0tSapbt26pdcePH1dISIiCg4PVu3dvbd68+VK0d8G2b9+uoKAgNW7cWPfdd592795dYu3lckzz8vL00Ucf6cEHHyz1h8ad9Zieb+fOncrIyHA4dj4+PoqKiirx2FXmM19dZWdny2azlfk7qBX5LFQny5cvl7+/v5o1a6ZHH31Uhw8fLrH2cjmumZmZWrBggRISEsqsddbjWl6EKid06NAh5efnF/l5nICAAGVkZBS7TEZGRoXqq6OCggKNGDFCN954o1q1alViXbNmzfTBBx/oyy+/1EcffaSCggJ17NhRe/fuvYTdVlxUVJSSk5OVkpKi6dOna+fOnercubOOHTtWbP3lcEwlad68ecrKylJ8fHyJNc56TItTeHwqcuwq85mvjk6dOqUxY8Zo4MCBpf7gbkU/C9VFjx499OGHHyotLU0vv/yyVqxYoZ49eyo/P7/Y+svluM6aNUt16tRR3759S61z1uNaEfxMDZzGsGHDtGnTpjKvwUdHRys6Otr+vGPHjmrRooXeeecdvfDCCxe7zUrr2bOn/d9t2rRRVFSUQkJC9Omnn5br/wCd1b/+9S/17NlTQUFBJdY46zHF/3PmzBndc889MsZo+vTppdY662dhwIAB9n+3bt1abdq0UXh4uJYvX65u3bpVYWcX1wcffKD77ruvzC+POOtxrQjOVDmh+vXrq0aNGsrMzHSYnpmZqcDAwGKXCQwMrFB9dZOYmKj58+dr2bJlatiwYYWWdXV11XXXXacdO3ZcpO4uDl9fXzVt2rTEvp39mErSH3/8oSVLluihhx6q0HLOekwl2Y9PRY5dZT7z1UlhoPrjjz+Umppa6lmq4pT1WaiuGjdurPr165fYt7MfV0n65ptvtG3btgp/hiXnPa6lIVQ5ITc3N0VGRiotLc0+raCgQGlpaQ7/N3+u6Ohoh3pJSk1NLbG+ujDGKDExUXPnztXSpUsVFhZW4XXk5+fr559/VoMGDS5ChxfP8ePH9dtvv5XYt7Me03PNnDlT/v7+iouLq9ByznpMJSksLEyBgYEOxy4nJ0dr1qwp8dhV5jNfXRQGqu3bt2vJkiWqV69ehddR1mehutq7d68OHz5cYt/OfFwL/etf/1JkZKTatm1b4WWd9biWqqpHyqNyPv74Y+Pu7m6Sk5PNL7/8YoYOHWp8fX1NRkaGMcaY+++/34wdO9Ze/91335maNWuaV155xWzZssWMHz/euLq6mp9//rmqdqFcHn30UePj42OWL19u9u/fb3+cOHHCXnP+vk6YMMEsWrTI/Pbbb2bdunVmwIABxsPDw2zevLkqdqHcnnzySbN8+XKzc+dO891335mYmBhTv359c+DAAWPM5XNMC+Xn55tGjRqZMWPGFJnn7Mf02LFjZsOGDWbDhg1GkvnnP/9pNmzYYP/G20svvWR8fX3Nl19+aX766SfTu3dvExYWZk6ePGlfxy233GLefPNN+/OyPvNVpbR9zcvLM3fccYdp2LCh2bhxo8Nn+PTp0/Z1nL+vZX0Wqkpp+3rs2DHz1FNPmfT0dLNz506zZMkSc/3115smTZqYU6dO2ddxORzXQtnZ2aZWrVpm+vTpxa7DWY6rlQhVTuzNN980jRo1Mm5ubqZ9+/Zm9erV9nldu3Y1gwYNcqj/9NNPTdOmTY2bm5u59tprzYIFCy5xxxUnqdjHzJkz7TXn7+uIESPsr0tAQIC57bbbzPr16y998xXUv39/06BBA+Pm5mauvvpq079/f7Njxw77/MvlmBZatGiRkWS2bdtWZJ6zH9Nly5YV+74t3KeCggLz/PPPm4CAAOPu7m66detW5HUICQkx48ePd5hW2me+qpS2rzt37izxM7xs2TL7Os7f17I+C1WltH09ceKE6d69u/Hz8zOurq4mJCTEDBkypEg4uhyOa6F33nnHeHp6mqysrGLX4SzH1Uo2Y4y5qKfCAAAArgCMqQIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqADi9pKQkRUREXNRt3HTTTRoxYoT9eWhoqKZOnXpRtwnAuRCqAFRb5weZkjz11FNFfgfxYlu7dq2GDh1arloCGHBlqFnVDQBAZRljlJ+fLy8vL3l5eV3Sbfv5+V3S7QGo/jhTBaBaio+P14oVK/T666/LZrPJZrMpOTlZNptNX3/9tSIjI+Xu7q5vv/22yOW/+Ph49enTRxMmTJCfn5+8vb31yCOPKC8vr1zbzs3N1QMPPCAvLy81aNBAr776apGac88+GWOUlJSkRo0ayd3dXUFBQXr88ccl/XW27Y8//tDIkSPt+yFJhw8f1sCBA3X11VerVq1aat26tebMmeOwjZtuukmPP/64nn76adWtW1eBgYFKSkpyqMnKytLDDz+sgIAAeXh4qFWrVpo/f759/rfffqvOnTvL09NTwcHBevzxx5Wbm1uu1wFAxRCqAFRLr7/+uqKjozVkyBDt379f+/fvV3BwsCRp7Nixeumll7Rlyxa1adOm2OXT0tK0ZcsWLV++XHPmzNEXX3yhCRMmlGvbo0eP1ooVK/Tll19q8eLFWr58udavX19i/eeff67XXntN77zzjrZv36558+apdevWkqQvvvhCDRs21MSJE+37IUmnTp1SZGSkFixYoE2bNmno0KG6//779f333zuse9asWapdu7bWrFmjyZMna+LEiUpNTZUkFRQUqGfPnvruu+/00Ucf6ZdfftFLL72kGjVqSJJ+++039ejRQ/369dNPP/2kTz75RN9++60SExPL9ToAqKCq/T1nAChZ165dzRNPPGF/vmzZMiPJzJs3z6Fu/Pjxpm3btvbngwYNMnXr1jW5ubn2adOnTzdeXl4mPz+/1G0eO3bMuLm5mU8//dQ+7fDhw8bT09Ohl5CQEPPaa68ZY4x59dVXTdOmTU1eXl6x6zy3tjRxcXHmySeftD/v2rWr6dSpk0NNu3btzJgxY4wxxixatMi4uLiYbdu2Fbu+hIQEM3ToUIdp33zzjXFxcTEnT54ssx8AFcOZKgBO54Ybbiizpm3btqpVq5b9eXR0tI4fP649e/aUutxvv/2mvLw8RUVF2afVrVtXzZo1K3GZu+++WydPnlTjxo01ZMgQzZ07V2fPni11O/n5+XrhhRfUunVr1a1bV15eXlq0aJF2797tUHf+mbgGDRrowIEDkqSNGzeqYcOGatq0abHb+PHHH5WcnGwfc+bl5aXY2FgVFBRo586dpfYHoOIYqA7A6dSuXbuqW3AQHBysbdu2acmSJUpNTdVjjz2mKVOmaMWKFXJ1dS12mSlTpuj111/X1KlT1bp1a9WuXVsjRowoMu7r/OVtNpsKCgokSZ6enqX2dfz4cT388MP28V3natSoUUV2EUA5EKoAVFtubm7Kz8+v1LI//vijTp48aQ8eq1evlpeXl31cVknCw8Pl6uqqNWvW2IPH0aNH9euvv6pr164lLufp6alevXqpV69eGjZsmJo3b66ff/5Z119/fbH78d1336l3797629/+Jumv8VG//vqrWrZsWe59bNOmjfbu3atff/212LNV119/vX755Rddc8015V4ngMrj8h+Aais0NFRr1qzRrl27dOjQIfsZmvLIy8tTQkKCfvnlFy1cuFDjx49XYmKiXFxK/8+el5eXEhISNHr0aC1dulSbNm1SfHx8qcslJyfrX//6lzZt2qTff/9dH330kTw9PRUSEmLfj5UrV+rPP//UoUOHJElNmjRRamqqVq1apS1btujhhx9WZmZmufdPkrp27aouXbqoX79+Sk1N1c6dO/X1118rJSVFkjRmzBitWrVKiYmJ2rhxo7Zv364vv/ySgerARUKoAlBtPfXUU6pRo4ZatmwpPz+/IuONStOtWzc1adJEXbp0Uf/+/XXHHXcUuR1BSaZMmaLOnTurV69eiomJUadOnRQZGVliva+vr9577z3deOONatOmjZYsWaKvvvpK9erVkyRNnDhRu3btUnh4uP3+Vs8995yuv/56xcbG6qabblJgYKD69OlT7v0r9Pnnn6tdu3YaOHCgWrZsqaefftp+VqxNmzZasWKFfv31V3Xu3FnXXXedxo0bp6CgoApvB0DZbMYYU9VNAICV4uPjlZWVpXnz5lV1KwCuIJypAgAAsAChCsAVZffu3Q63GDj/UZFLjABwLi7/AbiinD17Vrt27SpxfmhoqGrW5IvRACqOUAUAAGABLv8BAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABb4/wBmQEKzCDegTgAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%sqlplot histogram --table no_outliers --column trip_distance --with no_outliers"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "daefb93a-f9c1-489d-876d-a2269e1d7bfd",
   "metadata": {},
   "source": [
    "## Clean up\n",
    "\n",
    "To stop and remove the container:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "299b6951-3b86-4b11-9394-ad5fd091c577",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CONTAINER ID   IMAGE                          COMMAND            CREATED          STATUS          PORTS                                        NAMES\n",
      "cefe171d72a8   clickhouse/clickhouse-server   \"/entrypoint.sh\"   51 seconds ago   Up 49 seconds   8123/tcp, 9009/tcp, 0.0.0.0:9000->9000/tcp   clickhouse\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "docker container ls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "id": "2a7e4faa-086e-4309-85af-77c033100dc0",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "clickhouse\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "docker container stop clickhouse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "id": "864f0097-176a-4f50-b33f-e6c91524ef38",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "clickhouse\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "docker container rm clickhouse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "id": "f561ce67-edee-405a-b2f8-13f19ad7ad34",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "docker container ls"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
